<?php

//控制器
class controller{
    private $applicationHelper;
    private function __construct()
    {
    }

    static function run(){
        $instance = new Controller();
        $instance->init();
        $instance->handleRequest();
    }

    function init(){
        $applicationHealper = ApplicationHelper::instance();
        $applicationHealper->init();
    }

    function handleRequest(){
        $request = new Request();
        $cmd_r = new CommandResolver();
        $cmd = $cmd_r->getCommand($request);
        $cmd->execute($request);
    }
}

class ApplicationHelper{
    private static $instance;
    private $config = '/tmp/data/woo_options.xml';

    private function __construct()
    {
    }

    static function instance(){
        if(!isset($instance)){
            self::$instance = new self();
        }
        return self::$instance;
    }

    function init(){
        //通过注册去获取配置文件的信息
        $dsn = ApplicationRegistry::getDSN();
        if(!is_null($dsn)){
            return ;
        }
        $this->getOptions();
    }

    private function getOptions(){
        $this->ensure(file_exists($this->config),'找不到配置文件');
        $options = SimpleXml_load_file($this->config);
        get_class($options);
        $dsn = (string)$options->dsn;
        $this->ensure($dsn,'没找到DSN');
        ApplicationRegistry::setDSN($dsn);
        //设置其他值
    }

    private function ensure($expr,$message){
        if(!$expr){
            throw new AppException($message);
        }
    }
}


//命令类 决定请求返回那个对象的实例
class CommandResolver{
    private static $base_cmd;
    private static $default_cmd;

    function __construct()
    {
        if(!self::$base_cmd){
            self::$base_cmd = new \ReflectionClass('Command');
            self::$default_cmd = new DefaultCommand();
        }
    }

    function getCommand(Request $request){
        $cmd = $request->getProperty('cmd');
        $sep = DIRECTORY_SEPARATOR;
        if(!$cmd){
            return self::$default_cmd;
        }
        $cmd = str_replace(array('.',$sep),'',$cmd);
        $filePath = "woo{$sep}command{$sep}{$cmd}.php";
        $className = "woo\\command\\{$cmd}";
        if(file_exists($filePath)){
            @require_once("$filePath");
            if(class_exists($className)){
                $cmd_class = new ReflectionClass($className);
                if($cmd_class->isSubclassOf(self::$base_cmd)){
                    return $cmd_class->newInstance();
                }else{
                    $request->addFeedback("command '$cmd' 不是 command");
                }
            }
        }

        $request->addFeedback("command '$cmd' 不是 command");
        return clone self::$default_cmd;
    }
}

//请求
class Request{
    private $properties;
    private $feedback = array();

    function __construct()
    {
        $this->init();
        RequestRegistry::setRequest($this);
    }

    function init(){
        if(isset($_SERVER['REQUEST_METHOD'])){
            $this->properties = $_REQUEST;
            return ;
        }

        foreach($_SERVER['argv'] as $arg){
            if(strpos($arg,'=')){
                list($key,$val) = explode('=',$arg);
                $this->setProperty($key,$val);
            }
        }
    }

    function getProperty($key){
        if(isset($this->properties[$key])){
            return $this->properties[$key];
        }
    }

    function setProperty($key,$val){
        $this->properties[$key] = $val;
    }

    function addFeedBack($msg){
        array_push($this->feedback,$msg);
    }

    function getFeedBack(){
        return $this->feedback;
    }

    function getFeedBackString($separator = '\n'){
        return implode($separator,$this->feedback);
    }
}


//命令
abstract class Command{
    final function __construct()
    {
    }

    //这个方法是为了做一些初始化操作或者数据清理之类的，这样的话对下面的所有命令对象都有效！
    function execute(Request $request){
        $this->doExcute($request);
    }

    abstract function doExcute(Request $request);
}

class DefaultCommand extends Command{
    function doExcute(Request $request){
        $request->addFeedBack('welcome to Woo');
        include('woo/view/main.php');
    }
}